#include "stdafx.h"
#include "PGN.h"


CPGN::CPGN()
{
}


CPGN::~CPGN()
{
}

uint CPGN::MoveToPGN( CBoard * board, uint move, char * s )
{
    CMoveList   list[1];
    CMove       mgen[1];
    uint color = board->GetColor();

    // default
    strcpy_s( s, 10, "-");

    // is move legal?
    if ( mgen->Do( board, move ) )
    {
        uint under_check = ( ( board->UnderCheck( color ) ) );
        mgen->Undo( board, move );
        if ( under_check ) return 0;
    } else return 0;

    uint to   = BYTE_FROM_UINT(move, 0);
    uint from = BYTE_FROM_UINT(move, 1);
    uint kill = BYTE_FROM_UINT(move, 2);
    uint flag = BYTE_FROM_UINT(move, 3);
    uint pie = board->Get( from );
    uint impossible_move = 0;

    // default
    strcpy_s( s, 10, "-");

    if      ( flag == CASTLE_WK ) strcpy_s( s, 10, "O-O");
    else if ( flag == CASTLE_WQ ) strcpy_s( s, 10, "O-O-O");
    else if ( flag == CASTLE_BK ) strcpy_s( s, 10, "O-O");
    else if ( flag == CASTLE_BQ ) strcpy_s( s, 10, "O-O-O");
    else {
        // piece to move
        switch( GET_PIE(pie)  ){
            case PAWN:      strcpy_s( s, 10, ""); break;  
            case KNIGHT:    strcpy_s( s, 10, "N"); break;  
            case BISHOP:    strcpy_s( s, 10, "B"); break;  
            case ROOK  :    strcpy_s( s, 10, "R"); break;  
            case QUEEN :    strcpy_s( s, 10, "Q"); break;  
            case KING  :    strcpy_s( s, 10, "K"); break;  
        }
        uint say_file = 0;
        uint say_row  = 0;
        list->Reset();
        mgen->GenAll( board, list, board->GetColor() );
        list->Start();
        while( !list->IsEmpty() )
        {
            uint lm = list->GetMove( );
            // cout << "lm = "<<lm << "  move = "<< move<<endl;
            // possible move
            uint lm_to   = BYTE_FROM_UINT( lm, 0);
            uint lm_from = BYTE_FROM_UINT( lm, 1);
            uint lm_kill = BYTE_FROM_UINT( lm, 2);
            uint lm_flag = BYTE_FROM_UINT( lm, 3);
            uint lm_pie  = board->Get( lm_from );
            if ( mgen->Do( board, lm ) )
            {
                if ( !( board->UnderCheck( color ) ) )
                {
                    if ( (lm_to == to) && ( lm_pie == pie ) && ( lm_flag == flag ) && ( lm != move ) )
                    { // does not work with 3 pieces
                        if ( HASH_FILE[from] == HASH_FILE[lm_from] )
                            say_row = 1;
                        else 
                            say_file = 1; 
                    }
                } // else if ( lm == move ) impossible_move = 1;
                mgen->Undo( board, lm );
            } // else if ( lm == move ) impossible_move = 1;
            list->Next();   
        }
        if ( say_file || (kill && ( GET_PIE(pie) == PAWN )) || (flag == ENPASSANT) ) 
            strcat_s( s, 5, FILE_NAME[ HASH_FILE[from] ]);
        if ( say_row )  strcat_s( s, 5, ROW_NAME[ HASH_ROW[from] ]);
        if ( (flag == ENPASSANT) || ( kill ) ) strcat_s( s, 5, "x");
        strcat_s( s, 10, SQ_NAME64[ MAILBOX[ to ] ]);
        if ( GET_COLOR( flag ) ) {
            strcat_s( s, 10, "=");
            strcat_s( s, 10, WPIE_NAME[ GET_PIE(flag) ]);
        }
    }
    if ( impossible_move ) strcpy_s( s, 10, "oops");
    return 0;
}

uint CPGN::PrintAllMovesPGN( CBoard * board )
{
    CMoveList   list[1];
    CMove       move[1];
    char        pgn[256];
    move->GenAll( board, list );
    list->Start();

    while( !list->IsEmpty() )
    {
        //cout << "Move "<< list->GetMove() << " = ";
        MoveToPGN( board, list->GetMove(), pgn );
        cout << pgn <<endl;
        list->Next();
    }

    return 0;
}